typedef unsigned char uint8_t;
typedef unsigned int  uint32_t;
typedef uint32_t      size_t;

extern char __bss[], __bss_end[], __stack_top[];

// segment initialization
void *memset(void *buf,  char c, size_t n) 
{
    uint8_t *p = (uint8_t *) buf;
    while (n--)
        *p++ = c;
    return buf;
}

void kernel_main(void) 
{
    memset(__bss, 0, (size_t)__bss_end - (size_t)__bss);

    for (;;);
}

__attribute__((section(".text.boot")))  // the placement of function in the ld script
__attribute__((naked))                  // Don't generate unnecessary cod    
void boot(void) 
{
    __asm__ __volatile__(
        "mv sp, %[stack_top]\n"         // set stack region, the end address
        "j kernel_main\n"               // jump to kernel_main
        :
        : [stack_top] "r" (__stack_top) // pass the stack top as %[stack_top]
    );
}